为保证API的安全调用,在调用API时阿里云会对每个API请求通过签名(Signature)进行身份验证。无论使用HTTP还是HTTPS协议提交请求,都需要在请求中包含签名信息。
签名算法
本文介绍函数计算API签名步骤,SDK中已经实现了签名算法并对API进行签名,无需您手动计算。具体信息,请参见SDK列表。
对于每一个请求,函数计算服务会根据请求头部的Authorization
字段来校验是否合法(设置了HTTP触发器的允许匿名访问的函数除外)。客户端须使用与函数计算服务端一致的签名算法才能通过验证,对于未包含签名字段或者签名错误的请求,函数计算将会返回HTTP 403
错误。
signature = base64(hmac-sha256(HTTP_METHOD + "\n"
+ CONTENT-MD5 + "\n"
+ CONTENT-TYPE + "\n"
+ DATE + "\n"
+ CanonicalizedFCHeaders
+ CanonicalizedResource))
// Authorization字段介绍
Authorization = "FC " + accessKeyID + ":" + signature
参数说明如下:
HTTP_METHOD
:大写的HTTP方法,例如PUT、GET、POST、DELETE。CONTENT-MD5
:请求内容数据的MD5值。如果请求的Header中没有传Content-MD5,则此处填入空串。CONTENT-TYPE
:请求内容的类型,函数计算的类型是application/json
。DATE
:此次操作的时间,不能为空,支持时区为GMT的RFC1123格式,例如Mon, 02 Jan 2006 15:04:05 GMT
。注意 客户端需要保证生成的时间与服务端的时间相差不超过15分钟,否则函数服务将拒绝此次请求。CanonicalizedFCHeaders
:所有以x-fc-
为前缀的HTTP头组成的字符串。生成方式,请参见CanonicalizedFCHeaders。CanonicalizedResource
:请求的URL的Path,一般是先对收到的Path解码,再去掉请求的Path里的Params内容。- Path的结构为:
$api-version/api-path
api-version
:API版本,目前版本为2016-08-15
。api-path
:访问各个接口的路径,例如创建Service为/services
,其他Path,请参见API概览。
- 需要认证的HTTP触发器与其他请求的
CanonicalizedResource
不同,下面对这两种情况分别进行介绍。- 需要认证的HTTP触发器请求:如果有Params,则以回车符
\n
分隔各个参数,Params中的各个参数key-value对按照字母序进行排序。如果没有Params则以\n
补齐。 例如:// 需要认证的HTTP触发器的URL的真实Path /2016-08-15/proxy/service-name/func-name/path-with-%20-space/action?x=1&a=2&x=3&with%20space=foo%20bar // URL decode后的结果 /2016-08-15/proxy/service-name/func-name/path-with- -space/action?x=1&a=2&x=3&with space=foo bar // 需要认证的HTTP触发器的CanonicalizedResource /2016-08-15/proxy/service-name/func-name/path-with- -space/action\na=2\nwith space=foo bar\nx=1\nx=3 // 普通请求的URL的真实Path /2016-08-15/service-name/func-name/path-with-%20-space/action?x=1&a=2&x=3&with%20space=foo%20bar // URL解码后的结果 /2016-08-15/service-name/func-name/path-with- -space/action?x=1&a=2&x=3&with space=foo bar // 普通请求的CanonicalizedResource /2016-08-15/service-name/func-name/path-with- -space/action
说明 如果Params里的key对应多个value,即对key-value整体进行排序。 - 普通请求:首先对收到的Path进行URL解码,普通请求的
CanonicalizedResource
会只取到?
前面的内容,即舍弃传入的各个Params
。说明 普通请求是除了需要访问带认证的HTTP触发器的请求外的所有请求。
- 需要认证的HTTP触发器请求:如果有Params,则以回车符
- Path的结构为:
hmac-sha256
:需要以您的AccessKey Secret为Key。您可以通过以下伪代码确认签名的实现方式:
// 构造字符串的过程 function composeStringToSign(method, path, headers, queries) { var contentMD5 = headers['content-md5'] || ''; var contentType = headers['content-type'] || ''; var date = headers['date']; var signHeaders = buildCanonicalHeaders(headers, 'x-fc-'); var u = url.parse(path); var pathUnescaped = decodeURIComponent(u.pathname); var str = `${method}\n${contentMD5}\n${contentType}\n${date}\n${signHeaders}${pathUnescaped}`; if (queries) { var params = []; Object.keys(queries).forEach(function (key) { var values = queries[key]; var type = typeof values; if (type === 'string') { params.push(`${key}=${values}`); return; } if (type === 'object' && values instanceof Array) { queries[key].forEach(function (value) { params.push(`${key}=${value}`); }); } }); params.sort(); str += '\n' + params.join('\n'); } return str; } // 使用HMAC-SHA256和Base64计算签名的过程,其中Source参数为构造出的字符串。 function signString(source, secret) { const buff = crypto.createHmac('sha256', secret) .update(source, 'utf8') .digest(); return new Buffer(buff, 'binary').toString('base64'); }
CanonicalizedFCHeaders
完成以下操作,构造阿里云规范头,操作步骤如下: